From 180211a7532d1a7b2f71dc8a6267bedcef86a3c8 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 21 Feb 2007 10:13:40 +0000 Subject: [PATCH] x86: Allow exceptions to be handled while interrupts are disabled. Handlers must take special care if necessary. Fixes the debug 'd' key. Signed-off-by: Keir Fraser --- xen/arch/x86/traps.c | 10 +++++++--- xen/arch/x86/x86_32/entry.S | 4 ++-- xen/arch/x86/x86_64/entry.S | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 3eff302b7e..145056e49c 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -625,7 +625,8 @@ asmlinkage int do_invalid_op(struct cpu_user_regs *regs) if ( unlikely(!guest_mode(regs)) ) { struct bug_frame bug; - if ( (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) && + if ( is_kernel(regs->eip) && + (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) && (memcmp(bug.ud2, "\xf\xb", sizeof(bug.ud2)) == 0) && (memcmp(bug.mov, BUG_MOV_STR, sizeof(bug.mov)) == 0) && (bug.ret == 0xc2) ) @@ -877,6 +878,9 @@ static int fixup_page_fault(unsigned long addr, struct cpu_user_regs *regs) return 0; } + ASSERT(!in_irq()); + ASSERT(regs->eflags & X86_EFLAGS_IF); + if ( VM_ASSIST(d, VMASST_TYPE_writable_pagetables) && guest_kernel_mode(v, regs) && /* Do not check if access-protection fault since the page may @@ -904,8 +908,6 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs) unsigned long addr, fixup; int rc; - ASSERT(!in_irq()); - addr = read_cr2(); DEBUGGER_trap_entry(TRAP_page_fault, regs); @@ -1916,6 +1918,8 @@ void unset_nmi_callback(void) asmlinkage int math_state_restore(struct cpu_user_regs *regs) { + BUG_ON(!guest_mode(regs)); + setup_fpu(current); if ( current->arch.guest_context.ctrlreg[0] & X86_CR0_TS ) diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index 286c4b5fb7..1de36aa3e7 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -424,7 +424,7 @@ handle_exception: testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%esp) jz exception_with_ints_disabled sti # re-enable interrupts - xorl %eax,%eax +1: xorl %eax,%eax movw UREGS_entry_vector(%esp),%ax movl %esp,%edx pushl %edx # push the cpu_user_regs pointer @@ -451,7 +451,7 @@ exception_with_ints_disabled: call search_pre_exception_table addl $4,%esp testl %eax,%eax # no fixup code for faulting EIP? - jz FATAL_exception_with_ints_disabled + jz 1b movl %eax,UREGS_eip(%esp) movl %esp,%esi subl $4,%esp diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 36b5c5e1ad..cffd89dced 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -362,7 +362,7 @@ ENTRY(handle_exception) testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%rsp) jz exception_with_ints_disabled sti - movq %rsp,%rdi +1: movq %rsp,%rdi movl UREGS_entry_vector(%rsp),%eax leaq exception_table(%rip),%rdx GET_CURRENT(%rbx) @@ -388,7 +388,7 @@ exception_with_ints_disabled: movq %rsp,%rdi call search_pre_exception_table testq %rax,%rax # no fixup code for faulting EIP? - jz FATAL_exception_with_ints_disabled + jz 1b movq %rax,UREGS_rip(%rsp) subq $8,UREGS_rsp(%rsp) # add ec/ev to previous stack frame testb $15,UREGS_rsp(%rsp) # return %rsp is now aligned? -- 2.30.2